package com.hivemq.extensions.rbac.model;

import com.alibaba.druid.pool.DruidPooledConnection;
import com.blxt.utils.check.CheckUtils;
import com.hivemq.extension.sdk.api.annotations.NotNull;
import com.qjava.qsql.postgresql.DBPoolConnection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;


/**
 * 产品设备授权检查
 * <p> 从数据库获取绑定信息
 * <p> 不存在绑定就认为授权失败
 * @Author: Zhang.Jialei
 * @Date: 2020/8/3 14:02
 */
public class ProductDevieAuthCheck {

    private static final @NotNull Logger log = LoggerFactory.getLogger(ProductDevieAuthCheck.class);

    public ProductDevieAuthCheck() {

    }


    /**
     * 检查设备&产品关系是否成立
     * @param userKey        产品key
     * @param userSecret     产品秘钥
     * @param devicekey         设备秘钥
     * @return
     */
    public Device ckeck(String userKey, String userSecret,String devicekey){

        return queryDevice(devicekey, userKey, userSecret);
    }

    /**
     * 执行sql查询
     * @return
     */
    public synchronized ResultSet executeQuery(String sql){
        DruidPooledConnection connection = null;
        try {
            DBPoolConnection dbPoolConnection = DBPoolConnection.getInstance();
            connection  =  dbPoolConnection.getConnection();
        } catch (SQLException throwables) {
            connection = null;
            throwables.printStackTrace();
        }

        if(connection == null){
            return null;
        }
        final ResultSet resultSet;
        try {
            PreparedStatement pst = connection.prepareStatement(sql);
            resultSet = pst.executeQuery();
            return resultSet;
        } catch (SQLException throwables) {
            throwables.printStackTrace();
            return null;
        }finally {
            try {
                connection.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
    }
    /**
     * 直接查询
     * @param deviceKey
     * @param userKey
     * @param userSecret
     * @return
     */
    public Device queryDevice(String deviceKey, String userKey, String userSecret){
        String sql = String.format("select product_key,group_key from \"mqtt\".\"ut_device_product\"  " +
                        "WHERE device_key = '%s' AND  user_key = '%s' AND user_secret = '%s' LIMIT 1",
                deviceKey, userKey, userSecret);
        final ResultSet resultSet;

        // 连接
        DruidPooledConnection connection = null;
        try {
            DBPoolConnection dbPoolConnection = DBPoolConnection.getInstance();
            CheckUtils.objectCheck(dbPoolConnection, "Druid未初始化", "0001", "");

            connection  =  dbPoolConnection.getConnection();
            CheckUtils.objectCheck(dbPoolConnection, "Druid连接申请失败", "0001", "");

            // 执行查询
            PreparedStatement pst = connection.prepareStatement(sql);
            resultSet = pst.executeQuery();

            // 查询结果解析
            while(resultSet.next()){
                Device device = new Device();
                device.setProduct_key(resultSet.getString("product_key"));
                // 没有注册到产品,就返回空
                if(device.getProduct_key() == null){
                    return null;
                }
                device.setDevice_key(deviceKey);
                device.setUser_key(userKey);
                device.setGroup_key(resultSet.getString("group_key"));
                return device;
            }

        } catch (SQLException throwables) {
            connection = null;
            log.error("查询出错");
            throwables.printStackTrace();
        }finally {
            // 关闭连接
            if(connection != null){
                try {
                    connection.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }

        }

        return null;
    }

}
